package com.googlecode.yoohoo.io.socket;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.mina.common.CloseFuture;
import org.apache.mina.common.IoSession;
import org.apache.mina.common.WriteFuture;
import org.osgi.framework.BundleContext;

import com.googlecode.yoohoo.xmppcore.connection.IConnectionContext;

public class AbstractConnectionContext implements IConnectionContext {
	protected IoSession ioSession;
	protected Map<Object, Object> attributes;
	protected BundleContext bundleContext;
	
	public AbstractConnectionContext(IoSession ioSession, BundleContext bundleContext) {
		this.ioSession = ioSession;
		this.bundleContext = bundleContext;
		attributes = new HashMap<Object, Object>();
	}

	@Override
	public void close() {
		close(false);
	}

	@Override
	public boolean close(boolean sync) {
		write("</stream:stream>", true);
		CloseFuture future = ioSession.close();
		if (sync) {
			future.join();
		}
		
		return future.isClosed();
	}

	@Override
	public Object getAttribute(Object key) {
		return attributes.get(key);
	}

	@Override
	public Object getAttribute(Object key, Object defaultValue) {
		Object value = attributes.get(key);
		
		return value == null ? defaultValue : value;
	}

	@Override
	public Map<Object, Object> getAttributes() {
		return attributes;
	}

	@Override
	public Set<Object> getAttributesKeys() {
		return attributes.keySet();
	}

	@Override
	public String getConnectorType() {
		return "socket";
	}

	@Override
	public Object removeAttribute(Object key) {
		return attributes.remove(key);
	}

	@Override
	public void setAttribute(Object key, Object value) {
		attributes.put(key, value);
	}

	@Override
	public boolean write(Object message, boolean sync) {
		WriteFuture future = ioSession.write(message);
		if (sync) {
			future.join();
		}
		
		return future.isWritten();
	}

	@Override
	public void write(Object message) {
		write(message, false);
	}
	
	public BundleContext getBundleContext() {
		return bundleContext;
	}
	
	public IoSession getIoSession() {
		return ioSession;
	}

}
